﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;

namespace AEA.RSSFeedReaderLib
{
    /// <summary>
    /// Class to handle import/export of Feed data.
    /// </summary>
    public class ImportExportSettings
    {
        /// <summary>
        /// Import feeds from XML data file.
        /// </summary>
        /// <param name="file">The XML file to import.</param>
        /// <returns>A List of Feeds as string</returns>
        public static List<string> Import(string file)
        {
            List<string> feedsToReturn = new List<string>();

            try
            {
                XmlSerializer xmlSer = new XmlSerializer(typeof(RSSFeed));
                using (Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    RSSFeed rssFeed = (RSSFeed)xmlSer.Deserialize(stream);
                    stream.Close();

                    foreach (ChannelFeed channelFeed in rssFeed.Channels)
                        feedsToReturn.Add(channelFeed.ChannelUri);
                }
            }
            catch(Exception ex)
            {
                // Could not load the file.
                throw new ImportExportException(string.Format("Error importing file {0}", file),
                    file, ex);
            }

            return feedsToReturn;
        }

        /// <summary>
        /// Export feed data to a XML file.
        /// </summary>
        /// <param name="file">Where to save the XMl file.</param>
        /// <param name="data">The data to save to the XML file.</param>
        /// <returns>True if export succeeds, false otherwise.</returns>
        public static bool Export(string file, RSSFeed data)
        {
            try
            {
                XmlSerializer xmlSer = new XmlSerializer(typeof(RSSFeed));
                using (Stream stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    xmlSer.Serialize(stream, data);
                }
                return true;
            }
            catch (Exception ex)
            {
                throw new ImportExportException(string.Format("Error exporting the file to {0}", file),
                    file, ex);
            }
        }
    }

    /// <summary>
    /// Returns detailed information about the last exception.
    /// </summary>
    public class ImportExportException : Exception
    {
        private string _message;

        /// <summary>
        /// Initialize a new instance of the AEA.RSSFeedReaderLib.ImportExportException class.
        /// </summary>
        public ImportExportException() { }

        /// <summary>
        /// Initializes a new instance of the AEA.RSSFeedReaderLib.ImportExportException class with a specified error message
        /// and the file which is being used.
        /// </summary>
        /// <param name="message">The error message that explains the reason for the exception.</param>
        /// <param name="file">The file that is associated with the current exception.</param>
        public ImportExportException(string message,string file)
        {
            _message = message;
            File = file;
        }

        /// <summary>
        /// Initializes a new instance of the AEA.RSSFeedReaderLib.ImportExportException class with a specified error message,
        /// a reference to the file which is being used and a reference to the inner exception that is the cause of
        /// this exception.
        /// </summary>
        /// <param name="message">The error message that explains the reason for the exception.</param>
        /// <param name="file">The file that is associated with the current exception.</param>
        /// <param name="innerException">The exception that is the cause of the current exception, or a null reference
        /// if no inner exception is specified.</param>
        public ImportExportException(string message, string file, Exception innerException) 
        {
            _message = message;
            File = file;
            InnerException = innerException;            
        }

        /// <summary>
        /// Gets a message that describes the current exception.
        /// </summary>
        public override string Message
        {
            get
            {
                return _message;
            }
        }

        /// <summary>
        /// Gets the file that is associated with the current exception.
        /// </summary>
        public string File { get; private set; }

        /// <summary>
        /// Gets the System.Exception instance that caused the current exception.
        /// </summary>
        public new Exception InnerException { get; private set; }
    }
}
